
#ifndef EWPAINTER_H
#define EWPAINTER_H

#include "GUI.h"

typedef GUI_COLOR ewColor_t;
typedef GUI_POINT ewPoint_t;
typedef GUI_RECT ewRect_t;
typedef GUI_FONT ewFont_t;
typedef GUI_BITMAP ewBitmap_t;

enum ewLineStyle_t {
    LineStyleSolid = GUI_LS_SOLID,
    LineStyleDash = GUI_LS_DASH,
    LineStyleDot = GUI_LS_DOT,
    LineStyleDashDot = GUI_LS_DASHDOT,
    LineStyleDashDotDot = GUI_LS_DASHDOTDOT
};


enum ewTextAlign_t {
    TextAlignTop = GUI_TA_TOP,
    TextAlignBottom = GUI_TA_BOTTOM,
    TextAlignVertCenter = GUI_TA_VCENTER,
    TextAlignLeft = GUI_TA_LEFT,
    TextAlignRight = GUI_TA_RIGHT,
    TextAlignHorizCenter = GUI_TA_HCENTER
};

enum ewRotation_t {
    Rotation_0 = 0,
    Rotation_180,
    Rotation_CCW,
    Rotation_CW
};

enum ewWrapMode_t {
    WrapModeNone = GUI_WRAPMODE_NONE,
    WrapModeWord = GUI_WRAPMODE_WORD,
    WrapModeChar = GUI_WRAPMODE_CHAR
};

enum ewTextMode_t {
    TextModeNormal = GUI_TEXTMODE_NORMAL,
    TextModeTransparent = GUI_TEXTMODE_TRANS,
    TextModeReverse = GUI_TEXTMODE_REV,
    TextModeXor = GUI_TEXTMODE_XOR
};

enum ewTextStyle_t {
    TextStyleNormal = GUI_TS_NORMAL,
    TextStyleUnderline = GUI_TS_UNDERLINE,
    TextStyleStrikeThru = GUI_TS_STRIKETHRU,
    TextStyleOverline = GUI_TS_OVERLINE
};

#define EW_BLUE 		(GUI_BLUE)
#define EW_GREEN 		(GUI_GREEN)
#define EW_RED 			(GUI_RED)
#define EW_CYAN			(GUI_CYAN)
#define EW_MAGENTA		(GUI_MAGENTA)
#define EW_YELLOW		(GUI_YELLOW)
#define EW_LIGHTBLUE	(GUI_LIGHTBLUE)
#define EW_LIGHTGREEN	(GUI_LIGHTGREEN)
#define EW_LIGHTRED		(GUI_LIGHTRED)
#define EW_LIGHTCYAN	(GUI_LIGHTCYAN)
#define EW_LIGHTMAGENTA	(GUI_LIGHTMAGENTA)
#define EW_LIGHTYELLOW	(GUI_LIGHTYELLOW)
#define EW_DARKBLUE		(GUI_DARKBLUE)
#define EW_DARKGREEN	(GUI_DARKGREEN)
#define EW_DARKRED		(GUI_DARKRED)
#define EW_DARKCYAN		(GUI_DARKCYAN)
#define EW_DARKMAGENTA	(GUI_DARKMAGENTA)
#define EW_DARKYELLOW	(GUI_DARKYELLOW)
#define EW_WHITE		(GUI_WHITE)
#define EW_LIGHTGRAY	(GUI_LIGHTGRAY)
#define EW_GRAY			(GUI_GRAY)
#define EW_DARKGRAY		(GUI_DARKGRAY)
#define EW_BLACK		(GUI_BLACK)
#define EW_BROWN		(GUI_BROWN)
#define EW_ORANGE		(GUI_ORANGE)
#define EW_TRANSPARENT	(GUI_TRANSPARENT)

#define EW_INVALID_COLOR	(GUI_INVALID_COLOR)


/**
 * This is a wrapper class for the drawing primitives in
 * the emwin GUI interface.
 */
class EwPainter {
public:



    EwPainter();

    void enableAlpha(bool on);
    ewColor_t getBackgroundColor();
    void setBackgroundColor(ewColor_t c);
    ewColor_t getColor();
    void setColor(ewColor_t c);

    uint8_t getPenSize();
    void setPenSize(uint8_t size);

    void move(int32_t dx, int32_t dy);
    void moveTo(int32_t x, int32_t y);

    void clear();
    void clearRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
    void copyRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t width, int32_t height);

    void drawHorizGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, ewColor_t c0, ewColor_t c1);
    void drawVertGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, ewColor_t c0, ewColor_t c1);
    void drawHorizRoundGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius, ewColor_t c0, ewColor_t c1);
    void drawVertRoundGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius, ewColor_t c0, ewColor_t c1);

    void drawPixel(int32_t x, int32_t y);
    void drawPoint(int32_t x, int32_t y);
    void drawRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
    void drawRect(ewRect_t *rect);
    void drawRoundedFrame(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius, int32_t width);
    void drawRoundedRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius);

    void fillRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
    void fillRect(ewRect_t *rect);
    void fillRoundedRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius);

    void drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
    void drawLine(int32_t dx, int32_t dy);
    void drawLineTo(int32_t x, int32_t y);
    void drawHorizLine(int32_t y, int32_t x0, int32_t x1);
    void drawVertLine(int32_t x, int32_t y0, int32_t y1);

    void drawPolyLine(ewPoint_t* pPoints, int numPoints, int32_t x, int32_t y);

    ewLineStyle_t getLineStyle();
    ewLineStyle_t setLineStyle(ewLineStyle_t style);

    void drawPolygon(ewPoint_t* pPoints, int numPoints, int32_t x, int32_t y);
    void enlargePolygon(ewPoint_t* pDest, ewPoint_t* pSrc, int numPoints, int32_t len);
    void magnifyPolygon(ewPoint_t* pDest, ewPoint_t* pSrc, int numPoints, int32_t mag);
    void rotatePolygon(ewPoint_t* pDest, ewPoint_t* pSrc, int numPoints, float angle);
    void fillPolygon(ewPoint_t* pPoints, int numPoints, int32_t x, int32_t y);

    void drawCircle(int32_t x0, int32_t y0, int32_t radius);
    void fillCircle(int32_t x0, int32_t y0, int32_t radius);

    void drawEllipse(int32_t x0, int32_t y0, int32_t rx, int32_t ry);
    void fillEllipse(int32_t x0, int32_t y0, int32_t rx, int32_t ry);

    void drawArc(int32_t xCenter, int32_t yCenter, int32_t rx, int32_t ry, int32_t a0, int32_t a1);
    void drawGraph(int16_t* paY, int numPoints, int32_t x0, int32_t y0);
    void drawPie(int32_t x0, int32_t y0, int32_t radius, int32_t a0, int32_t a1);

    void drawChar(uint16_t c);
    void drawChar(uint16_t c, int32_t x, int32_t y);
    void drawChars(uint16_t c, int32_t cnt);
    void newLine();
    void drawString(const char* s, int32_t maxLen = -1);
    void drawString(const char* s, int32_t x, int32_t y);
    void drawStringClearEOL(const char* s, int32_t x, int32_t y);
    void drawStringHorizCenter(const char* s, int32_t x, int32_t y);
    void drawStringRect(const char* s, ewRect_t *pRect, ewTextAlign_t align, ewWrapMode_t wrap = WrapModeNone);
    void drawStringRect(const char* s, ewRect_t *pRect, ewTextAlign_t align, int32_t maxLen, ewRotation_t rotation);
    int32_t getNumWrapLines(const char* s, int32_t width, ewWrapMode_t wrap);

    ewTextMode_t getTextMode();
    void setTextMode(ewTextMode_t mode);
    void setTextStyle(ewTextStyle_t style);
    ewTextAlign_t getTextAlign();
    void setTextAlign(ewTextAlign_t align);

    bool setTextPosition(int32_t x, int32_t y);
    void getTextPosition(int32_t &x, int32_t &y);

    const ewFont_t* setFont(const ewFont_t* pFont);
    const ewFont_t* getFont();
    int32_t getCharWidth(uint16_t c);
    int32_t getFontHeight();
    int32_t getFontDistY();
    int32_t getLeadingBlankCols(uint16_t c);
    int32_t getTrailingBlankCols(uint16_t c);
    int32_t getStringWidth(const char* s);
    bool isCharInFont(const ewFont_t* pFont, uint16_t c);

    void drawBitmap(const ewBitmap_t* pBm, int32_t x, int32_t y);
    void drawBitmapMagnified(const ewBitmap_t* pBm, int32_t x, int32_t y, int32_t xMul, int32_t yMul);
    void drawBitmapScaled(const ewBitmap_t* pBm, int32_t x, int32_t y, int32_t xCenter, int32_t yCenter, int32_t xMag, int32_t yMag);

    void drawJpeg(const void* pData, int32_t dataSize, int32_t x, int32_t y);
    void drawJpegScaled(const void* pData, int32_t dataSize, int32_t x, int32_t y, int32_t num, int32_t denom);
    void getJpegSize(const void* pData, int32_t dataSize, int32_t &width, int32_t &height);

    void drawGif(const void* pData, int32_t dataSize, int32_t x, int32_t y, int32_t imgIdx = -1);
    void drawGifScaled(const void* pData, int32_t dataSize, int32_t x, int32_t y, int32_t imgIdx, int32_t num, int32_t denom);
    void getGifSize(const void* pData, int32_t dataSize, int32_t &width, int32_t &height);
    int32_t getGifNumImages(const void* pData, int32_t dataSize);

    void drawPng(const void* pData, int32_t dataSize, int32_t x, int32_t y);
    void getPngSize(const void* pData, int32_t dataSize, int32_t &width, int32_t &height);


    void saveContext();
    void restoreContext();


private:


    GUI_CONTEXT _context;
    bool _contextSaved;

};

#endif
